home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / wfimage / src / waveforms.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-09-14  |  19.0 KB  |  480 lines

  1. /*______________________________________________________________________________________
  2.  |                                                                                      |
  3.  |    waveforms image                                                                   |
  4.  |    Copyright (c) 2000 stranded UFO productions                                       |
  5.  |    Written by Paul Juhasz                                                            |
  6.  |______________________________________________________________________________________*/
  7.  
  8.  
  9. #include "waveforms.h"
  10. #include "waveforms_protos.h"
  11.  
  12.  
  13. #undef  SysBase
  14. #undef  GfxBase
  15. #undef  IntuitionBase
  16. #undef  UtilityBase
  17. #define SysBase                  cb->cb_SysBase
  18. #define GfxBase                  cb->cb_GfxBase
  19. #define IntuitionBase            cb->cb_IntuitionBase
  20. #define UtilityBase              cb->cb_UtilityBase
  21.  
  22. #ifdef DOUBLEMATH
  23. #define MathIeeeDoubBasBase      cb->cb_MathIeeeDoubBasBase
  24. #define MathIeeeDoubTransBase    cb->cb_MathIeeeDoubTransBase
  25. #endif /* DOUBLEMATH */
  26.  
  27.  
  28. /*______________________________________________________________________________________
  29.  |                                                                                      |
  30.  |    Inquire for attribute tag values of the waveform.image                            |
  31.  |______________________________________________________________________________________*/
  32.  
  33. STATIC ULONG getAttrsMethod( Class *cl, struct Image *im, struct opGet *msg )
  34. {
  35.    struct waveformData *wfd  = INST_DATA( cl, im );
  36.  
  37.    switch ( msg->opg_AttrID )
  38.    {
  39.       case WFI_WaveType:
  40.          *msg->opg_Storage = (ULONG)wfd->wf_WaveType;
  41.          break;
  42.  
  43.       case WFI_WaveShape:
  44.          *msg->opg_Storage = (ULONG)wfd->wf_WaveShape;
  45.          break;
  46.  
  47.       case WFI_Outline:
  48.          *msg->opg_Storage = (ULONG)wfd->wf_Outline;
  49.          break;
  50.  
  51.       case WFI_OsciPen:
  52.          *msg->opg_Storage = (ULONG)wfd->wf_OsciPen;
  53.          break;
  54.  
  55.       case WFI_ZeroPen:
  56.          *msg->opg_Storage = (ULONG)wfd->wf_ZeroPen;
  57.          break;
  58.  
  59.       /* Let the superclass try */
  60.       default:
  61.          return((ULONG)DoSuperMethodA( cl, (Object *)im, (Msg)msg ));
  62.    }
  63.    return( 1UL );
  64. }
  65.  
  66.  
  67. /*______________________________________________________________________________________
  68.  |                                                                                      |
  69.  |    Update the waveform.image from tag values and prepare it                          |
  70.  |______________________________________________________________________________________*/
  71.  
  72. STATIC LONG setAttrsMethod( Class *cl, struct Image *im, struct opSet *msg, BOOL init )
  73. {
  74.    struct WFIBase      *cb   = (struct WFIBase *)cl->cl_Dispatcher.h_Data;
  75.    struct waveformData *wfd  = INST_DATA( cl, im );
  76.    struct TagItem      *tags = msg->ops_AttrList, *tstate, *tag;
  77.    ULONG                tidata;
  78.    LONG                 refresh = 0L;
  79.  
  80.    /* Initialize the variables */
  81.    tstate = tags;
  82.  
  83.    if ( init )       im->Width = im->Height = 64;
  84.  
  85.    else              refresh = DoSuperMethodA( cl, (Object *)im, (Msg)msg );
  86.  
  87.    while ( tag = NextTagItem( &tstate ))
  88.    {
  89.       tidata = tag->ti_Data;
  90.       switch ( tag->ti_Tag )
  91.       {
  92.          case SYSIA_DrawInfo:
  93.             wfd->wf_DrawInfo = (struct DrawInfo *)tidata;
  94.             break;
  95.  
  96.          case IA_BGPen:
  97.             wfd->wf_ShadowPen = (WORD)tidata;
  98.             refresh = 1;
  99.             break;
  100.  
  101.          case IA_FGPen:
  102.             wfd->wf_HiLitePen = (WORD)tidata;
  103.             refresh = 1;
  104.             break;
  105.  
  106.          case IA_Width:
  107.             im->Width = (WORD)tidata;
  108.             refresh = 1;
  109.             break;
  110.  
  111.          case IA_Height:
  112.             im->Height = (WORD)tidata;
  113.             refresh = 1;
  114.             break;
  115.  
  116.          case WFI_OsciPen:
  117.             wfd->wf_OsciPen = (WORD)tidata;
  118.             refresh = 1;
  119.             break;
  120.  
  121.          case WFI_WavePen:
  122.             wfd->wf_WavePen = (WORD)tidata;
  123.             refresh = 1;
  124.             break;
  125.  
  126.          case WFI_ZeroPen:
  127.             wfd->wf_ZeroPen = (WORD)tidata;
  128.             refresh = 1;
  129.             break;
  130.  
  131.          case WFI_WaveShape:
  132.             wfd->wf_WaveShape = tidata;
  133.             refresh = 1;
  134.             break;
  135.  
  136.          case WFI_WaveType:
  137.             wfd->wf_WaveType = tidata;
  138.             refresh = 1;
  139.             break;
  140.  
  141.          case WFI_Outline:
  142.             wfd->wf_Outline = tidata;
  143.             refresh = 1;
  144.             break;
  145.  
  146.          case WFI_BoxFrame:
  147.             wfd->wf_BoxFrame = tidata;
  148.             refresh = 1;
  149.             break;
  150.  
  151.          default:
  152.             break;
  153.       }
  154.    }
  155.  
  156.    /* Make sure we have valid pens and other sanity checks... */
  157.    if ( wfd->wf_DrawInfo ) {
  158.       if ( wfd->wf_ShadowPen == -1 )
  159.          wfd->wf_ShadowPen = wfd->wf_DrawInfo->dri_Pens[BLOCKPEN];
  160.       if ( wfd->wf_HiLitePen == -1 )
  161.          wfd->wf_HiLitePen = wfd->wf_DrawInfo->dri_Pens[DETAILPEN];
  162.       if ( wfd->wf_OsciPen == -1 )
  163.          wfd->wf_OsciPen = wfd->wf_DrawInfo->dri_Pens[BARBLOCKPEN];
  164.       if ( wfd->wf_WavePen == -1 )
  165.          wfd->wf_WavePen = wfd->wf_DrawInfo->dri_Pens[BARDETAILPEN];
  166.    }
  167.    if ( wfd->wf_ZeroPen == -1 )
  168.       wfd->wf_ZeroPen = wfd->wf_DrawInfo->dri_Pens[BARTRIMPEN];   //(LONG)wfd->wf_OsciPen;
  169.  
  170.    if (( wfd->wf_WaveType > WF_SQUARE_WAVE ) || ( wfd->wf_WaveType < WF_SINE_WAVE ))
  171.       wfd->wf_WaveType = WF_SINE_WAVE;
  172.    if (( wfd->wf_WaveShape > 98L ) || ( wfd->wf_WaveShape < -98L ))
  173.       wfd->wf_WaveShape = 0L;
  174.    if (( wfd->wf_Outline != WF_SOLID_DISPLAY ) && ( wfd->wf_Outline != WF_DOTTED_DISPLAY ))
  175.       wfd->wf_Outline = WF_DOTTED_DISPLAY;
  176.  
  177.    return( refresh );
  178. }
  179.  
  180.  
  181. /*__________________________________________________________________________________________
  182.  |                                                                                          |
  183.  |    Data for Sintable                                                                     |
  184.  |    As using Floating Point Numbers would be Tooooo Slow for the Computer to              |
  185.  |    attain a suitable frame rate the values are first all multiplied by 16384             |
  186.  |    which just happens to be 14 shifts left  (very helpfull) which gets                   |
  187.  |    rid of the decimal Point and then when multiplied with X or Y are then                |
  188.  |    Divided by 16384 (14 shifts right)                                                    |
  189.  |    Using this technique fast 3d graphics can be possible.                                |
  190.  |__________________________________________________________________________________________*/
  191.  
  192. /*__________________________________________________________________________________________
  193.  |                                                                                          |
  194.  |    Draw the selected waveform.image into the window                                      |
  195.  |__________________________________________________________________________________________*/
  196.  
  197. STATIC LONG drawMethod( Class *cl, struct Image *im, struct impDraw *msg )
  198. {
  199.    struct WFIBase         *cb = (struct WFIBase *)cl->cl_Dispatcher.h_Data;
  200.    struct waveformData    *wfd = INST_DATA( cl, im );
  201.    struct RastPort        *rp = msg->imp_RPort;
  202.    LONG                    wwid = im->Width - 1L, whgt = im->Height - 1L;
  203.    LONG                    tx = msg->imp_Offset.X, ty = msg->imp_Offset.Y,
  204.                            ix, gwid, ghgt, ghlf, gmid, shape, samval, samdiv,
  205.                            halfw, quart, incr, fram = 1L, dfram, amplitude;
  206. #ifdef DOUBLEMATH
  207.    double                  sinstep;
  208. #else
  209.    LONG                    sinstep;
  210.    const WORD              sin_tab[] = { 0,
  211.       286,   572,   857,  1143,  1428,  1713,  1997,  2280,  2563,  2845,  3126,  3406,  3686,
  212.      3964,  4240,  4516,  4790,  5063,  5334,  5604,  5872,  6138,  6402,  6664,  6924,  7182,
  213.      7438,  7692,  7943,  8192,  8438,  8682,  8923,  9162,  9397,  9630,  9860, 10087, 10311,
  214.     10531, 10749, 10963, 11174, 11381, 11585, 11786, 11982, 12176, 12365, 12551, 12733, 12911,
  215.     13085, 13255, 13421, 13583, 13741, 13894, 14044, 14189, 14330, 14466, 14598, 14726, 14849,
  216.     14968, 15082, 15191, 15296, 15396, 15491, 15582, 15668, 15749, 15826, 15897, 15964, 16026,
  217.     16083, 16135, 16182, 16225, 16262, 16294, 16322, 16344, 16362, 16374, 16382, 16384,  /*   90  */
  218.     16382, 16374, 16362, 16344, 16322, 16294, 16262, 16225, 16182, 16135, 16083, 16026, 15964,
  219.     15897, 15826, 15749, 15668, 15582, 15491, 15396, 15296, 15191, 15082, 14967, 14849, 14726,
  220.     14598, 14466, 14330, 14189, 14044, 13894, 13741, 13583, 13421, 13255, 13085, 12911, 12733,
  221.     12551, 12365, 12176, 11982, 11786, 11585, 11381, 11174, 10963, 10749, 10531, 10311, 10087,
  222.      9860,  9630,  9397,  9162,  8923,  8682,  8438,  8192,  7943,  7692,  7438,  7182,  6924,
  223.      6664,  6402,  6138,  5872,  5604,  5334,  5063,  4790,  4516,  4240,  3964,  3686,  3406,
  224.      3126,  2845,  2563,  2280,  1997,  1713,  1428,  1143,   857,   572,   286,     0,  /*  180  */
  225.      -286,  -572,  -857, -1143, -1428, -1713, -1997, -2280, -2563, -2845, -3126, -3406, -3686,
  226.     -3964, -4240, -4516, -4790, -5063, -5334, -5604, -5872, -6138, -6402, -6664, -6924, -7182,
  227.     -7438, -7692, -7943, -8192, -8438, -8682, -8923, -9162, -9397, -9630, -9860,-10087,-10311,
  228.    -10531,-10749,-10963,-11174,-11381,-11585,-11786,-11982,-12176,-12365,-12551,-12733,-12911,
  229.    -13085,-13255,-13421,-13583,-13741,-13894,-14044,-14189,-14330,-14466,-14598,-14726,-14849,
  230.    -14968,-15082,-15191,-15296,-15396,-15491,-15582,-15668,-15749,-15826,-15897,-15964,-16026,
  231.    -16083,-16135,-16182,-16225,-16262,-16294,-16322,-16344,-16362,-16374,-16382,-16384,  /*  270  */
  232.    -16382,-16374,-16362,-16344,-16322,-16294,-16262,-16225,-16182,-16135,-16083,-16026,-15964,
  233.    -15897,-15826,-15749,-15668,-15582,-15491,-15396,-15296,-15191,-15082,-14967,-14849,-14726,
  234.    -14598,-14466,-14330,-14189,-14044,-13894,-13741,-13583,-13421,-13255,-13085,-12911,-12733,
  235.    -12551,-12365,-12176,-11982,-11786,-11585,-11381,-11174,-10963,-10749,-10531,-10311,-10087,
  236.     -9860, -9630, -9397, -9162, -8923, -8682, -8438, -8192, -7943, -7692, -7438, -7182, -6924,
  237.     -6664, -6402, -6138, -5872, -5604, -5334, -5063, -4790, -4516, -4240, -3964, -3686, -3406,
  238.     -3126, -2845, -2563, -2280, -1997, -1713, -1428, -1143, -857,   -572,  -286,     0,     0
  239.    };
  240. #endif /* DOUBLEMATH */
  241.  
  242.  
  243.    /* Initialise the constants and variables that we need */
  244.    shape = wfd->wf_WaveShape;
  245.    SetBPen( rp, wfd->wf_OsciPen );
  246.  
  247.    SetAPen( rp, wfd->wf_OsciPen );                 /* switching to 'oscilloscope' colour */
  248.    RectFill( rp, tx, ty, tx + wwid, ty + whgt );      /* for the background */
  249.  
  250.    if ( wfd->wf_BoxFrame ) {
  251.       SetAPen( rp, wfd->wf_ShadowPen );            /* switching to shadow outline */
  252.       Move( rp, tx, ty + whgt );
  253.       Draw( rp, tx, ty );                             /* Draw half of the box */
  254.       Draw( rp, tx + wwid, ty );
  255.       SetAPen( rp, wfd->wf_HiLitePen );            /* switching to hilite outline */
  256.       Draw( rp, tx + wwid, ty + whgt );
  257.       Draw( rp, tx, ty + whgt );                      /* draw other half of box */
  258.       fram = ( wwid >= 25L ) ? ( wwid / 12L ) : 2L; /* adjust waveform to fit inside frame */
  259.    }
  260.  
  261.    dfram = fram * 2L;                           /* adjust frame thickness and inside area */
  262.    tx += fram; ty += fram;
  263.    gwid = wwid - dfram; ghgt = whgt - dfram;
  264.    gmid = ( gwid / 2 ); ghlf = ( ghgt / 2 );
  265.  
  266.    if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {
  267.       if ( wfd->wf_ZeroPen ) {
  268.          SetAPen( rp, wfd->wf_ZeroPen );           /* Draw the zero line when needed */
  269.          Move( rp, tx, ty + ghlf );
  270.          Draw( rp, tx + gwid, ty + ghlf );
  271.       }
  272.    }
  273.  
  274.    /* ...and all is ready now, so let's draw up the wave for display */
  275.    SetAPen( rp, wfd->wf_WavePen );
  276.  
  277.    switch ( wfd->wf_WaveType ) {
  278.  
  279.  
  280. #ifdef DOUBLEMATH                         /*    calculate sine wave using ieee library.  */
  281.                                           /*    ...... doesn't quite work yet            */
  282.       case WF_SINE_WAVE:                  /*    try: radiant = degrees * Pi / 180        */
  283.          sinstep = gwid / 360.0;
  284.          for ( ix = 0; ix < gwid; ix++ ) {
  285.             amplitude = IEEEDPSin( sinstep * ix ) * ghlf;
  286.             if ( wfd->wf_Outline == WF_SOLID_DISPLAY ) {
  287.                Move( rp, tx + ix, ty + ghlf );
  288.                Draw( rp, tx + ix, (LONG)(( ty + ghlf ) - amplitude ));
  289.             } else WritePixel( rp, tx + ix, (LONG)(( ty + ghlf ) - amplitude ));
  290.          }
  291.          break;
  292.  
  293. #else                                     /*    use the above pre-calculated sine-table.  */
  294.  
  295.       case WF_SINE_WAVE:
  296.          ix = 0L; sinstep = 0;
  297.          while ( ix < gwid ) {
  298.             amplitude = (( sin_tab[( sinstep / 100 )] * ghlf ) >> 14 );
  299.             sinstep += ( 36000 / gwid );
  300.             if ( wfd->wf_Outline == WF_SOLID_DISPLAY ) {
  301.                Move( rp, tx + ix, ty + ghlf );
  302.                Draw( rp, tx + ix, ((ty + ghlf ) - amplitude ));
  303.             } else      WritePixel( rp, tx + ix, (( ty + ghlf ) - amplitude ));
  304.             ix++;
  305.          }
  306.          break;
  307.  
  308. #endif /* DOUBLEMATH */
  309.  
  310.  
  311.       case WF_TRIANGULAR_WAVE:
  312.  
  313.          quart = gmid >> 1;
  314.          samval = 0; incr = ( ghlf * 1000 ) / quart;
  315.          for ( ix = 0; ix <= quart; ix++ ) {
  316.             samdiv = samval / 1000;
  317.             if ( wfd->wf_Outline == WF_SOLID_DISPLAY ) {
  318.                Move( rp, tx + ix, ty + ghlf );
  319.                Draw( rp, tx + ix, ty + ghlf - samdiv );              /* first quarter */
  320.                Move( rp, tx + ( gmid - ix ), ty + ghlf );
  321.                Draw( rp, tx + ( gmid - ix ), ty + ghlf - samdiv );   /* second quarter */
  322.                Move( rp, tx + gmid + ix, ty + ghlf );
  323.                Draw( rp, tx + gmid + ix, ty + ghlf + samdiv );       /* third quarter */
  324.                Move( rp, tx + gmid + gmid - ix, ty + ghlf );
  325.                Draw( rp, tx + gmid + gmid - ix, ty + ghlf + samdiv );   /* fourth quarter */
  326.             } else {
  327.                WritePixel( rp, tx + ix, ( ty + ghlf - samdiv ));
  328.                WritePixel( rp, tx + ( gmid - ix ), ( ty + ghlf - samdiv ));
  329.                WritePixel( rp, tx + ( gmid + ix ), ( ty + ghlf + samdiv ));
  330.                WritePixel( rp, tx + ( gwid - ix ), ( ty + ghlf + samdiv ));
  331.             }
  332.             samval += incr;
  333.          }
  334.          break;
  335.  
  336.       case WF_RAMPUP_WAVE:
  337.          samval = ( ghlf * 1000 );
  338.          incr = -(( ghlf * 1000 ) / gmid );
  339.          if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {               /* first vertical */
  340.             Move( rp, tx, ty + ghlf );
  341.             Draw( rp, tx, ty + ghlf + ghlf );
  342.          }
  343.          for ( ix = 1; ix < gwid; ix++ ) {
  344.             if ( wfd->wf_Outline == WF_SOLID_DISPLAY ) {
  345.                Move( rp, tx + ix, ty + ghlf );
  346.                Draw( rp, tx + ix, ty + ghlf + samval / 1000 );
  347.             } else      WritePixel( rp, tx + ix, ( ty + ghlf + samval / 1000 ));
  348.             samval += incr;
  349.          }
  350.          if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {
  351.             Move( rp, tx + ix, ty );
  352.             Draw( rp, tx + ix, ty + ghlf );                       /* last vertical */
  353.          }
  354.          break;
  355.  
  356.       case WF_RAMPDOWN_WAVE:
  357.          samval = -( ghlf * 1000 );
  358.          incr = (( ghlf * 1000 ) / gmid );
  359.          if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {            /* first vertical */
  360.             Move( rp, tx, ty );
  361.             Draw( rp, tx, ty + ghlf );
  362.          }
  363.          for ( ix = 1; ix < gwid; ix++ ) {
  364.             if ( wfd->wf_Outline == WF_SOLID_DISPLAY ) {
  365.                Move( rp, tx + ix, ty + ghlf );
  366.                Draw( rp, tx + ix, ty + ghlf + samval / 1000 );
  367.             } else      WritePixel( rp, tx + ix, ( ty + ghlf + samval / 1000 ));
  368.             samval += incr;
  369.          }
  370.          if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {
  371.             Move( rp, tx + ix, ty + ghlf );
  372.             Draw( rp, tx + ix, ty + ghlf + samval / 1000 );       /* last vertical */
  373.          }
  374.          break;
  375.  
  376.       case WF_SQUARE_WAVE:
  377.          halfw = gmid;
  378.          halfw += (( gmid * shape ) / 100 );
  379.          if ( halfw <= 1 )             halfw += 1;
  380.          if ( halfw >= ( gwid - 1 ))   halfw -= 1;
  381.          if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {            /* first vertical */
  382.             Move( rp, tx, ty + ghlf );
  383.             Draw( rp, tx, ty + 1 );
  384.          }
  385.          for ( ix = 1; ix < halfw; ix++ ) {
  386.             if ( wfd->wf_Outline == WF_SOLID_DISPLAY ) {
  387.                Move( rp, tx + ix, ty + ghlf );
  388.                Draw( rp, tx + ix, ty + 1 );
  389.             } else      WritePixel( rp, tx + ix, ( ty + 1 ));
  390.          }
  391.          if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {            /* middle vertical */
  392.             Move( rp, tx + ix, ty + 1 );
  393.             Draw( rp, tx + ix, ty + ghgt - 1 );
  394.          }
  395.          for ( ix = halfw; ix < gwid; ix++ ) {
  396.             if ( wfd->wf_Outline == WF_SOLID_DISPLAY ) {
  397.                Move( rp, tx + ix, ty + ghlf );
  398.                Draw( rp, tx + ix, ty + ghgt - 1 );
  399.             } else      WritePixel( rp, tx + ix, ( ty + ghgt - 1 ));
  400.          }
  401.          if ( wfd->wf_Outline == WF_DOTTED_DISPLAY ) {            /* last vertical */
  402.             Move( rp, tx + ix, ty + ghlf );
  403.             Draw( rp, tx + ix, ty + ghgt - 1 );
  404.          }
  405.          break;
  406.  
  407.       default: break;
  408.    }
  409.  
  410.    tx -= fram; ty -= fram;                               /* reset frame coordinates */
  411.    SetAPen( rp, TEXTPEN );
  412.    return( 0 );
  413. }
  414.  
  415.  
  416.  
  417. /*______________________________________________________________________________________
  418.  |                                                                                      |
  419.  |    Create a new waveform.image                                                       |
  420.  |______________________________________________________________________________________*/
  421.  
  422. STATIC LONG newMethod( Class *cl, struct Image *im, struct opSet *msg )
  423. {
  424.    struct Image        *newobj;
  425.  
  426.    /* Create the new object */
  427.    if ( newobj = (struct Image *)DoSuperMethodA( cl, (Object *)im, (Msg)msg ))
  428.       setAttrsMethod( cl, newobj, msg, TRUE );   /* Update the attributes */
  429.    return((LONG)newobj );
  430. }
  431.  
  432.  
  433.  
  434. /*______________________________________________________________________________________
  435.  |                                                                                      |
  436.  |    The waveform.image class dispatcher                                               |
  437.  |______________________________________________________________________________________*/
  438.  
  439. LONG __asm dispatchWFI( REGISTER __a0 Class *cl, REGISTER __a2 struct Image *im,
  440.                            REGISTER __a1 ULONG *msg )
  441. {
  442.    LONG                 retval;
  443.  
  444.    if ( cl->cl_UserData )     putreg( REG_A4, (LONG)cl->cl_UserData );
  445.  
  446.    switch ( *msg )
  447.    {
  448.       case OM_NEW:
  449.          retval = newMethod( cl, im, (struct opSet *)msg );
  450.          break;
  451.  
  452.       case OM_SET:
  453.       case OM_UPDATE:
  454.          retval = setAttrsMethod( cl, im, (struct opSet *)msg, FALSE );
  455.          break;
  456.  
  457.       case OM_GET:
  458.          retval = getAttrsMethod( cl, im, (struct opGet *)msg );
  459.          break;
  460.  
  461.       case IM_DRAW:
  462.          retval = drawMethod( cl, im, (struct impDraw *)msg );
  463.          break;
  464.  
  465.       case OM_DISPOSE:
  466.          retval = (LONG)DoSuperMethodA( cl, (Object *)im, ( Msg )msg );
  467.          break;
  468.  
  469.       default:
  470.          retval = (LONG)DoSuperMethodA( cl, (Object *)im, ( Msg )msg );
  471.          break;
  472.  
  473.    }
  474.    return( retval );
  475. }
  476.  
  477.  
  478.  
  479.  
  480.